/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 combat_creature.h

	$Header: /heroes4/combat_creature.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined( COMBAT_CREATURE_H_INCLUDED )
#define COMBAT_CREATURE_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <list>
#include <map>
#include "abstract_combat_creature.h"
#include "animated_window_ptr.h"
#include "animation_ptr.h"
#include "attackable_object.h"
#include "combat_actor.h"
#include "combat_actor_action.h"
#include "combat_creature_handler.h"
#include "combat_creature_list.h"
#include "combat_creature_ptr.h"
#include "combat_cursor_mode.h"
#include "creature_int_map.h"
#include "playing_sound_ptr.h"
#include "sound_cache.h"
#include "spell.h"
#include "spell_list.h"

class	t_abstract_grail_data_source;
class	t_combat_action_message;
class	t_combat_ai_melee_action;
struct	t_combat_creature_ai_data;
class	t_combat_path_finder;
class	t_creature_array;
struct	t_creature_influence;
class	t_player;
class	t_spell_effect_window;
class	t_stationary_combat_object;
enum	t_wall_bonus;
class	t_window;

enum t_cheating_state
{
	k_not_cheating,
	k_cheating_adam, // tattooed guy with shotgun
	k_cheating_jack, // tottering guy with walker.

	k_cheating_count
};

typedef t_counted_ptr<t_combat_ai_melee_action> t_ai_melee_action_ptr;

// ------------------------------------------------------------------------------
// pointer to creature influence structure
// ------------------------------------------------------------------------------
typedef t_counted_ptr<t_creature_influence> t_creature_influence_ptr;

// ------------------------------------------------------------------------------
// list of influences
// ------------------------------------------------------------------------------
class t_influence_list : public std::list<t_creature_influence_ptr>
{
};

// ------------------------------------------------------------------------------
// bonuses received by influence
// ------------------------------------------------------------------------------
struct t_creature_influence_bonus
{
	t_creature_influence_bonus();

	std::vector<t_creature_ability> abilities;
	int								artifact_defense_bonus;
	int								artifact_luck_bonus;
	int								artifact_morale_bonus;
	int								artifact_move_bonus;
	int								artifact_offense_bonus;
	int								artifact_speed_bonus;
	int								artifact_spell_cost_modifier;
	std::vector<t_spell>			artifact_spell_effects;
	t_spell_immunity_array			artifact_spell_immunities;
	bool							binding;        // creature is bound by influencer
	int								defense_bonus;  // from defense skill
	int								leadership_luck_bonus;
	int								leadership_morale_bonus;
	int								magic_resistance;
	int								offense_bonus; // from offense skill
	int								tactics_move_bonus;
	int								tactics_speed_bonus;
};

// ------------------------------------------------------------------------------
// bonus + corresponding creature + position of influence item in other list
// ------------------------------------------------------------------------------
struct t_creature_influence : public t_counted_object, public t_creature_influence_bonus
{
	t_creature_influence( t_creature_influence_bonus const& bonus, 
		                  t_combat_creature* new_creature );

	t_combat_creature_ptr	   creature;
	t_influence_list::iterator list_position;
};

#if _MSC_VER > 1000

// Disable the "inherits via dominance" warning.  We know perfectly well
// that abstract_combat_creature overrides classes from t_wounds.
#pragma warning( push )
#pragma warning( disable: 4250 ) 
#endif

// ------------------------------------------------------------------------------
// t_combat_actor class
// ------------------------------------------------------------------------------

class t_combat_creature : public t_combat_actor, public t_abstract_combat_creature,
                          public t_attackable_object, public t_uncopyable
{
public:
	typedef t_counted_ptr<t_spell_effect_window> t_spell_effect_ptr;

	// Types
	// Constructor/Destructor
	t_combat_creature( t_battlefield& battlefield );
	t_combat_creature( t_battlefield&			battlefield,
					   t_creature_stack*		creature,
					   int						original_slot,
	                   t_creature_array const*	army,
					   double					scale,
					   bool						defender,
					   t_player const*			owner );

	// Member functions
	void						add_creatures( int health );
	virtual int					add_damage( int amount, t_combat_creature* source,
		                                    bool check_luck, bool permanent,
											t_combat_action_message const & damage_message );
	void						add_martyr_client( t_combat_creature_ptr creature );
	void						add_movement( int amount );
	virtual void                add_poison( int amount, t_combat_creature const & source );
	void                        add_vampirism( int amount );
	int							adjust_attack_damage(int						base_damage, 
													 t_attackable_object const&	target, 
													 bool						ranged,
													 int						distance_moved,
													 t_wall_bonus				wall_bonus ) const;
	void						animate_death( bool show_animation, t_combat_action_message const & message );
	void						append_handler( t_combat_creature_handler new_action );
	void						apply_damage( bool show_death );
	virtual void				apply_damage( t_battlefield& battlefield, bool show_death );
	virtual bool				begin_panic( t_combat_creature const& attacker );
	virtual bool				blocks_movement() const;
	virtual bool				can_be_attacked() const;
	virtual bool				can_retaliate( t_combat_creature const& attacker, 
		                                       bool ranged, int turns = 1 ) const;
	bool					    can_use_rebirth() const;
	void						change_active_spell_effect();
	void                        change_morale( int amount );
	void                        change_spell_points( int amount );
	void                        check_blocking();
	bool						check_cowardice( t_combat_creature const& target ) const;
	bool						check_flinch( t_combat_action_message const & message );
	virtual bool				check_guardian_robe();
	bool                        check_influence( t_combat_creature* creature );
	void                        check_influences();
	void						clear_ai_variables();
	void						clear_all_spells( t_combat_action_message const & message );
	void						clear_bindings();
	void                        clear_influence();
	void                        clear_spell( t_spell spell, t_combat_action_message const & message );
	void						clear_martyr_clients();
	void                        check_morale();
	void                        check_poison();
	void                        decrement_durations();
	void                        expend_shot();
	void						fade_in( t_combat_action_message const & message );
	void						fade_out( t_combat_action_message const & message );
	void						fade_out( t_handler handler, t_combat_action_message const & message );
	virtual void				flinch( t_combat_creature const& attacker, t_combat_action_message const & message );
	t_spell_list const&         get_active_spells() const;
	int							get_adjusted_number( int damage ) const;
	int                         get_adjusted_speed() const;
	t_combat_creature_ai_data&	get_ai_data() const;
	double						get_ai_estimated_value( t_spell spell ) const;
	double						get_ai_melee_reduction() const;
	double						get_ai_melee_value_per_hit() const;
	double						get_ai_move_value( int change ) const;
	double						get_ai_ranged_reduction() const;
	double						get_ai_ranged_value_per_hit() const;
	double						get_ai_spellcasting_value_per_hit() const;
	double						get_ai_speed_value( int speed_change, int morale_change ) const;
	double						get_ai_tactics_value_per_hit() const;
	double						get_ai_value( int damage ) const;
	double						get_ai_value_per_action() const;
	double						get_ai_value_per_hit() const;
	t_combat_actor_action_id    get_animation_action() const;
	t_screen_point				get_animation_position( t_animation const* animation ) const;
	int							get_arc_attack() const;
	int							get_arc_threat() const;
	int							get_attack_range() const;
	virtual t_attackable_object* get_attackable_object();
	int                         get_attacks( bool ranged ) const;
	int			                get_base_luck() const;
	t_battlefield&				get_battlefield() const;
	t_combat_creature*			get_closest_melee_target() const;
	virtual int					get_combat_movement() const;
	double                      get_combat_value() const;
	virtual t_abstract_combat_object const*	get_const_object() const;
	virtual bool				get_controller() const;
	int							get_damage( t_attackable_object const& target, bool ranged,
								            int distance_moved, 
											t_wall_bonus wall_bonus ) const;
	double						get_damage_decrease_ai_value( double decrease ) const;
	double						get_damage_decrease_ai_value( double decrease, bool ranged ) const;
	virtual int					get_damage_high() const;
	int							get_damage_high( t_spell add_effect, t_spell ignore_effect ) const;
	double						get_damage_increase_ai_value( double increase ) const;
	double						get_damage_increase_ai_value( double increase, bool ranged ) const;
	virtual int					get_damage_low() const;
	int							get_damage_low( t_spell add_effect, t_spell ignore_effect  ) const;
	t_spell						get_default_spell() const;
	virtual float				get_defense_bonus( bool ranged ) const;
	double						get_defense_decrease_ai_value( double decrease, bool ranged ) const;
	double						get_defense_increase_ai_value( double increase, bool ranged ) const;
	virtual int					get_depth() const;
	int							get_edge_distance( t_combat_object_base const& object ) const;
	int							get_edge_distance( t_combat_object_base const&	object,
												   t_map_point_2d const&		cell_point ) const;
	int							get_edge_distance( t_map_point_2d const& cell ) const;
	int							get_edge_subcell_distance( t_map_point_2d const& subcell ) const;
	int							get_effect_duration( t_spell spell ) const;
	virtual t_abstract_grail_data_source const& get_grail_data() const;
	virtual int					get_hit_points() const;
	int							get_hit_points(t_spell ignore_effect) const;
	t_map_point_2d              get_impact_point( t_map_point_2d const& source_cell,
									              t_map_point_2d const& target_cell ) const;
	void						get_interfere_with_list( t_combat_creature_list& list ) const;
	void						get_interfere_with_list( t_combat_creature_list&	list,
														 t_map_point_2d const&		position,
														 t_direction				direction ) const;
	void						get_interfered_by_list( t_combat_creature_list& list ) const;
	void						get_interfered_by_list( t_combat_creature_list&	list,
													    t_map_point_2d const&	cell_position ) const;
	double						get_interference_bonus(void) const;
	t_combat_label*				get_label() const;
	virtual int                 get_luck() const;
	int							get_luck_without_spells() const;
	t_combat_creature_ptr       get_magic_leech_client() const;
	virtual int					get_magic_resistance( t_spell spell ) const;
	int							get_magic_resistance( t_combat_creature const& caster, t_spell spell ) const;
	t_combat_creature_ptr		get_martyr_protector() const;
	t_ai_melee_action_ptr		get_melee_action() const;
	int							get_melee_damage( t_attackable_object const&	target, 
												  // Defaults to get_combat_movement()
												  int							distance_moved ) const;
	void						get_melee_effect( t_combat_creature const&	target,
												  int						attack_distance,
												  t_creature_int_map&		damage_map ) const;
	void						get_melee_effect( t_combat_creature const&	target,
												  int						distance_moved,
												  t_creature_int_map&		damage_map,
												  t_attack_angle const&		attack_angle,
												  t_map_point_2d const&		target_position ) const;
	void						get_melee_exchange_effect( t_combat_creature const&	target,
														   int						distance_moved,
														   t_creature_int_map&		damage_map,
														   t_attack_angle const&	attack_angle,
														   t_map_point_2d const&	target_position,
														   bool						retaliate ) const;
	void						get_melee_exchange_effect( t_combat_creature const&	target,
														   int						distance_moved,
														   t_creature_int_map&		damage_map,
														   t_attack_angle const&	attack_angle,
														   t_map_point_2d const&	target_position,
														   bool						retaliate,
														   bool						attacker_has_first_strike,
														   bool						defender_has_first_strike ) const;
	t_pixel_24 const&			get_message_color() const;
	t_missile_type              get_missile_type() const;
	int                         get_morale() const;
	int							get_morale_without_spells() const;
	int                         get_new_poison() const;
	virtual int					get_normal_alpha() const;
	virtual std::string						get_object_name() const;
	virtual t_combat_object_type			get_object_type() const;
	virtual t_combat_object_list			get_objects() const;
	virtual float							get_offense( bool ranged ) const;
	t_combat_path_finder&		get_path_finder( bool ignore_friendly = false ) const;
	bool						get_plague_checked() const;
	bool                        get_poison_checked() const;
	t_map_point_3d				get_position_in_tower( t_stationary_combat_object* tower ) const;
	t_combat_cursor_mode		get_preferred_action() const;
	int							get_ranged_damage( t_combat_creature const&	target,
												   int						attacker_damage,
												   int						target_damage ) const;
	int							get_range_factor( t_map_point_2d const& target_cell ) const;
	int							get_remaining_hitpoints( ) const;
	double						get_retaliation_weight_reduction( bool ranged ) const;
	virtual int					get_speed() const;
	t_spell_effect_ptr	        get_spell_animation() const;
	int                         get_spell_chance( t_combat_creature const& target, 
		                                          t_spell spell ) const;
	virtual int                 get_spell_cost( t_spell spell ) const;
	int                         get_spell_damage( t_combat_creature const& target,
		                                          t_spell spell ) const;
	int							get_spell_damage( t_combat_creature const& target, t_spell spell, 
											      t_abstract_grail_data_source const & grail_data ) const;
	int						    get_spell_damage( t_combat_creature const& target, 
		                                          t_spell spell, int damage ) const;
	int							get_stoning_chance( t_combat_creature const& target ) const;
	int							get_tactics_defense_bonus() const;
	int							get_tactics_move_bonus() const;
	int							get_tactics_offense_bonus() const;
	int						    get_tactics_speed_bonus() const;
	t_threat_footprint const&	get_threat_footprint() const;
	double						get_threat_type_weight( bool ranged ) const;
	int							get_total_damage_high( t_attackable_object const& target, bool ranged,
													   int distance_moved, t_wall_bonus wall_bonus) const;
	int							get_total_damage_low( t_attackable_object const& target, bool ranged,
													  int distance_moved, t_wall_bonus wall_bonus) const;
	int							get_total_hits(bool include_guardian_angel = false, t_spell ignore_effect = k_spell_none) const;
	t_stationary_combat_object* get_tower() const;
	t_direction					get_wait_direction(t_direction current_direction) const;
	t_direction					get_wait_direction( t_direction				current_direction,
												    t_map_point_2d const&	cell_point ) const;
	bool                        got_bad_luck() const;
	bool                        got_bad_morale() const;
	bool                        got_good_luck() const;
	bool                        got_good_morale() const;
	virtual bool				has_ability( t_creature_ability ability ) const;
	bool						has_damage_spells() const;
	bool						has_leeched() const;
	bool                        has_magic_mirror() const;
	bool						has_missile_spells() const;
	bool						has_nonmissile_damage_spells() const;
	bool                        has_regenerated() const;
	int                         heal( int amount );
	bool						interferes( t_combat_creature const& target ) const;
	bool						interferes( t_map_point_2d const&		center, int	facing, 
										    t_combat_creature const&	target, 
											t_map_point_2d const&		target_cell ) const;
	virtual bool				is_alive() const;
	bool                        is_blocking_attack() const;
	bool                        is_busy() const;
	virtual bool				is_creature() const;
	bool                        is_defending() const;
	virtual bool				is_elevated() const;
	bool						is_flying() const;
	virtual bool				is_giant() const;
	bool						is_incapacitated() const;
	bool                        is_influence_set() const;
	virtual bool				is_native_terrain( t_terrain_type terrain ) const;
	bool						is_ranged() const;
	bool                        is_selected() const;
	virtual bool				is_underlay() const;
	bool                        is_waiting() const;
	void					    kill( int amount );
	void                        kill_permanently( int amount, t_combat_action_message const & message );
	bool						moves_before( t_combat_creature const& creature,
									          bool last_was_defender ) const;
	virtual void				on_battlefield_destruction();
	virtual void                on_moved( bool cell_changed );
	virtual void                on_moving();
	virtual void				on_placed();
	virtual void				on_removed();
	virtual void                on_turned();
	virtual void                on_turning();
	void						place_in_tower();
	void						place_in_tower( t_map_point_2d const& point );
	t_playing_sound_ptr         play_sound( t_combat_actor_action_id action,
		                                    bool looping = false ) const;
	void                        pre_action_flinch( t_combat_action_message const & message );
	virtual void				preload_flinch( t_combat_creature const& attacker );
	void                        process_new_turn();
	double						project_interference_bonus(int damage) const;
	int							project_ranged_damage( t_combat_creature const&		target, 
													   int&							retaliation,
													   t_combat_creature *&	retaliation_target ) const;
	virtual bool				read( t_combat_reader& reader );
	void						refresh_label_position( bool check_overlap );
	void						remove_bodies( int amount );
	void						remove_from_map();
	void						remove_from_tower();
	void						remove_martyr_client( t_combat_creature_ptr creature );
	void						resurrect( int healed, bool show_number = true );
	bool						robe_blocked_damage() const;
	void						set_ability( t_creature_ability ability, bool arg = true );
	void                        set_active_shadow( bool arg );
	virtual void                set_alpha( t_battlefield& battlefield, int arg );
	void						set_animation( t_counted_idle_processor* );
	void						set_animation( t_action_id action );
	void						set_animation( t_action_id action,
											   t_combat_action_message const & message );
	void						set_animation( t_action_id action,
		                                       t_combat_creature_handler end_handler );
	void						set_animation( t_action_id action,
		                                       t_combat_creature_handler end_handler,
											   t_combat_action_message const & message );
	void						set_animation( t_action_id action,
								               t_direction direction );
	void						set_animation( t_action_id action,
								               t_direction direction,
											   t_combat_action_message const & message );
	void						set_animation( t_action_id action,
								               t_direction direction,
										       t_combat_creature_handler );
	void						set_animation( t_action_id action,
								               t_direction direction,
										       t_combat_creature_handler,
											   t_combat_action_message const & message );
	void					    set_binding( t_combat_creature& target, t_combat_action_message const & message );
	void						set_block_chance( int arg );
	void						set_blocking( bool arg );
	void						set_cheating( t_cheating_state arg );
	void                        set_default_spell( t_spell spell );
	void                        set_defending( bool arg );
	void						set_guardian_robe( int arg );
	void                        set_influence();
	void					    set_label( t_combat_label* label );
	void                        set_leeched( bool arg );
	void					    set_magic_leech_client( t_combat_creature_ptr creature );
	void						set_martyr_protector( t_combat_creature_ptr creature );
	void						set_melee_action( t_ai_melee_action_ptr action );
	void						set_normal_alpha( int arg );
	void						set_number( int arg );
	void						set_plague_checked( bool arg );
	void                        set_poison_checked( bool arg );
	void						set_preferred_action( t_combat_cursor_mode action );
	void                        set_regenerated( bool arg = true );
	void						set_retaliated( bool arg );
	void						set_retaliation_weight_reduction( bool ranged, double arg );
	void                        set_selected( bool arg = true );
	void                        set_selection_shadow( bool arg = true );
	virtual void                set_spell( t_spell spell, 
										   t_combat_action_message const & message, 
										   int power = 0,
										   t_spell_source = k_spell_source_spell );
	void                        set_spell_animation( t_spell_effect_ptr window );
	void                        set_underlay( bool underlay );
	void						set_wait_animation();
	void                        set_waiting( bool arg );
	bool                        show_morale_animation();
	void						show_resurrection( t_combat_action_message const & message );
	void						update_retaliation( int time_stamp );
	void						use_guardian_angel();
	virtual bool				write( t_combat_writer& writer ) const;

private:
	void			add_influence( t_combat_creature* creature, t_creature_influence_bonus const& bonus );
	void			begin_rebirth();
	void			clear_spells( t_town_type alignment, t_combat_action_message const & message );
	bool			consider_active( t_spell spell, t_spell add_effect, t_spell ignore_effect) const;
	virtual void	do_update_original_army( t_creature_array** armies );
	int				get_damage_done_limit( bool ranged ) const;
	int				get_damage_taken_limit( bool ranged ) const;
	void			increase_permanent_death_count( int amount );
	void			increase_spell_points( int amount );
	void			initialize();
	void			place_in_tower( t_stationary_combat_object* tower );
	void			resolve_damage();
	void			set_sounds();
	void			show_angels( t_window*, int number );
	void			transfer_spells( t_creature_stack* stack );

	typedef t_counted_ptr<t_combat_label>			t_label_ptr;
	typedef t_owned_ptr<t_combat_creature_ai_data>	t_ai_data_ptr;

	// Data members
	t_combat_object_ptr     m_active_shadow;
	t_animation_ptr			m_active_spell_animation;
	t_animated_window_ptr	m_active_spell_animation_window;
	t_spell_list			m_active_spells;
	t_ai_data_ptr			m_ai_data;
	t_ai_melee_action_ptr	m_ai_melee_action;
	double					m_ai_retaliation_weight_reduction[2];
	int						m_artifact_move_bonus;
	int						m_artifact_spell_cost_modifier;
	t_battlefield&			m_battlefield;
	int						m_base_defense[2];
	bool                    m_blocking_attack;
	int						m_block_chance;
	t_cheating_state		m_cheating_state;
	t_spell                 m_default_spell;
	bool                    m_defending; // creature gets 20% defense bonus
	int						m_defense_added;
	float                   m_defense_bonus[2];
	bool                    m_got_bad_luck;
	bool                    m_got_bad_morale;
	bool                    m_got_good_luck;
	bool                    m_got_good_morale;
	bool					m_has_leeched;
	bool                    m_has_regenerated;
	bool					m_in_water;
	bool                    m_influence_set;
	t_influence_list		m_influenced_creatures;
	t_influence_list		m_influencing_creatures;
	int						m_guardian_angel_limit;
	int						m_guardian_robe_strength;
	bool					m_has_ability[k_ability_count];
	bool                    m_is_underlay;
	t_label_ptr				m_label;
	int						m_luck_bonus;
	t_combat_creature_ptr   m_magic_leech_client;
	int						m_magic_resistance_bonus;
	t_combat_creature_list  m_martyr_clients;
	t_combat_creature_ptr   m_martyr_protector;
	int                     m_morale;
	int                     m_morale_bonus;
	int                     m_morale_roll;
	bool                    m_morale_shown;
	int                     m_move_bonus;
	bool					m_new_damage_is_permanent;
	int                     m_new_poison;
	t_combat_creature_const_ptr m_new_poison_source;
	int						m_normal_alpha;
	bool					m_normally_has_ability[k_ability_count];
	int                     m_offense_bonus;
	bool					m_plague_checked;
	bool                    m_poison_checked;
	t_combat_cursor_mode	m_preferred_action;
	int						m_retaliation_time_stamp;
	bool					m_robe_blocked_damage;
	bool					m_selected;
	t_combat_object_ptr     m_selection_shadow;
	t_sound_ptr				m_sounds[k_combat_actor_action_count];
	t_spell_effect_ptr      m_spell_animation;
	int                     m_tactics_speed_bonus;
	int						m_terrain_defense;
	bool                    m_waiting;
};

#if _MSC_VER > 1000

// restore previous warning states - even though 4250 isn't really all that
// meaningful a warning.
#pragma warning( pop )
#endif

// ------------------------------------------------------------------------------
// t_combat_actor inline members
// ------------------------------------------------------------------------------
inline void t_combat_creature::add_movement( int amount )
{
	m_artifact_move_bonus += amount;
}

inline void t_combat_creature::apply_damage( bool show_death )
{
	apply_damage( m_battlefield, show_death );
}

inline bool t_combat_creature::can_use_rebirth() const
{
	if (is_active( k_spell_clone ) || get_salvageable_bodies() == 0)
		return false;
	if (is_active( k_spell_guardian_angel ))
		return true;
	return  has_ability( k_ability_rebirth )
			&& get_spell_points() >= get_spell_cost( k_spell_rebirth );
}

inline void t_combat_creature::change_morale( int amount )
{
	m_morale += amount;
}


inline bool t_combat_creature::consider_active( t_spell spell, t_spell add_effect, t_spell ignore_effect) const
{
	return (add_effect == spell) || (is_active( spell ) && ignore_effect != spell);
}

inline void t_combat_creature::expend_shot()
{
	if (!has_ability( k_ability_unlimited_shots ))
		--m_shots;
}

inline t_spell_list const& t_combat_creature::get_active_spells() const
{
	return m_active_spells;
}

inline t_combat_creature_ai_data& t_combat_creature::get_ai_data() const
{
	return *m_ai_data;
}

inline t_battlefield& t_combat_creature::get_battlefield() const
{
	return m_battlefield;
}

// ------------------------------------------------------------------------------
// find edge-to-edge distance of two creatures
// ------------------------------------------------------------------------------
inline int t_combat_creature::get_edge_distance(  t_combat_object_base const& object  ) const
{
	return get_edge_distance( object, get_cell_position() );
}

inline int t_combat_creature::get_effect_duration( t_spell spell ) const
{
	return m_spells[spell].duration;
}

inline void t_combat_creature::get_interfere_with_list( t_combat_creature_list& list ) const
{
	get_interfere_with_list( list, get_cell_position(), get_current_direction() );
}

inline void t_combat_creature::get_interfered_by_list( t_combat_creature_list&  list ) const
{
	get_interfered_by_list( list, get_cell_position() );
}

inline t_combat_creature_ptr t_combat_creature::get_magic_leech_client() const
{
	return m_magic_leech_client;
}

inline t_combat_creature_ptr t_combat_creature::get_martyr_protector() const
{
	return m_martyr_protector;
}

inline t_ai_melee_action_ptr t_combat_creature::get_melee_action() const
{
	return m_ai_melee_action;
}

inline bool t_combat_creature::get_plague_checked() const
{
	return m_plague_checked;
}

inline bool t_combat_creature::get_poison_checked() const
{
	return m_poison_checked;
}

inline t_combat_cursor_mode t_combat_creature::get_preferred_action() const
{
	return m_preferred_action;
}

inline
int t_combat_creature::get_range_factor( t_map_point_2d const& target_cell ) const
{
	int distance = get_edge_distance( target_cell ) >> k_battlefield_subcell_shift;

	return get_range_effect( distance, false );
}

inline double t_combat_creature::get_retaliation_weight_reduction( bool ranged ) const
{
	return m_ai_retaliation_weight_reduction[ranged];
}

inline t_counted_ptr<t_spell_effect_window> t_combat_creature::get_spell_animation() const
{
	return m_spell_animation;
}

inline 
int t_combat_creature::get_spell_damage( t_combat_creature const& target, t_spell spell, t_abstract_grail_data_source const & grail_data ) const
{
	int damage = get_spell_power( spell, grail_data );

	return get_spell_damage( target, spell, damage );
}

inline t_direction t_combat_creature::get_wait_direction(t_direction current_direction) const
{
	return get_wait_direction( current_direction, get_cell_position() );
}

inline bool t_combat_creature::got_bad_luck() const
{
	return m_got_bad_luck;
}

inline bool t_combat_creature::got_good_luck() const
{
	return m_got_good_luck;
}

inline bool t_combat_creature::has_leeched() const
{
	return m_has_leeched;
}

inline bool t_combat_creature::has_magic_mirror() const
{
	return has_ability( k_ability_magic_mirror ) || is_active( k_spell_magic_mirror );
}

inline bool t_combat_creature::has_regenerated() const
{
	return m_has_regenerated;
}

inline int t_combat_creature::heal( int amount )
{
	if (amount > m_wounds)
		amount = m_wounds;
	m_wounds -= amount;
	return amount;
}

inline bool t_combat_creature::is_blocking_attack() const
{
	return m_blocking_attack;
}

inline bool t_combat_creature::is_defending() const
{
	return m_defending;
}

inline bool	t_combat_creature::is_flying() const
{
	if (is_active( k_spell_bind_flyer ))
		return false;
	return has_ability( k_ability_flying ) || is_active( k_spell_flight );
}

inline bool t_combat_creature::is_selected() const
{
	return m_selected;
}

inline bool t_combat_creature::is_waiting() const
{
	return m_waiting;
}

inline void t_combat_creature::remove_bodies( int amount )
{
	m_permanent_deaths += amount;
}

inline bool t_combat_creature::robe_blocked_damage() const
{
	return m_robe_blocked_damage;
}

inline void t_combat_creature::set_ability( t_creature_ability ability, bool arg )
{
	m_has_ability[ability] = arg;
	m_normally_has_ability[ability] = arg;
}	

inline void	t_combat_creature::set_animation( t_counted_idle_processor* animation )
{
	t_combat_actor::set_animation( animation );
}

inline void t_combat_creature::set_animation( t_action_id action,
											  t_combat_creature_handler handler )
{
	set_animation( action, m_current_direction, handler );
}

inline void t_combat_creature::set_animation( t_action_id action )
{
	set_animation( action, m_current_direction );
}

inline void t_combat_creature::set_animation( t_action_id action,
											  t_combat_creature_handler handler,
											  t_combat_action_message const & message )
{
	set_animation( action, m_current_direction, handler, message );
}

inline void t_combat_creature::set_animation( t_action_id action, t_combat_action_message const & message )
{
	set_animation( action, m_current_direction, message );
}

inline void t_combat_creature::set_block_chance( int arg )
{
	m_block_chance = arg;
}

inline void t_combat_creature::set_blocking( bool arg )
{
	m_blocking_attack = arg;
}

inline void t_combat_creature::set_cheating( t_cheating_state arg )
{
	m_cheating_state = arg;
	if (arg != k_not_cheating && m_shots < 10)
		m_shots = 10;
}

inline void t_combat_creature::set_default_spell( t_spell spell )
{
	m_default_spell = spell;
	m_preferred_action = k_combat_mode_spell; 
}

inline void t_combat_creature::set_defending( bool arg )
{
	m_defending = arg;
}

inline void t_combat_creature::set_guardian_robe( int arg )
{
	m_guardian_robe_strength = arg;
}

inline void t_combat_creature::set_magic_leech_client( t_combat_creature_ptr creature )
{
	m_magic_leech_client = creature;
}

inline void t_combat_creature::set_melee_action( t_ai_melee_action_ptr action )
{
	m_ai_melee_action = action;
}

inline void t_combat_creature::set_normal_alpha( int arg )
{
	m_normal_alpha = arg;
}

inline void t_combat_creature::set_number( int arg )
{
	m_number = arg;
}

inline void t_combat_creature::set_plague_checked( bool arg )
{
	m_plague_checked = arg;
}

inline void t_combat_creature::set_poison_checked( bool arg )
{
	m_poison_checked = arg;
}

inline void t_combat_creature::set_preferred_action( t_combat_cursor_mode action )
{
	m_preferred_action = action;
}

inline void t_combat_creature::set_regenerated( bool arg )
{
	m_has_regenerated = arg;
}

inline void t_combat_creature::set_retaliation_weight_reduction( bool ranged, double arg )
{
	m_ai_retaliation_weight_reduction[ranged] = arg;
}

inline void t_combat_creature::set_leeched( bool arg )
{
	m_has_leeched = arg;
}

inline void t_combat_creature::set_selected( bool arg )
{
	m_selected = arg;
}

// -----------------------------------------------------------------------
// set current spell for creature
// -----------------------------------------------------------------------
inline void t_combat_creature::set_spell_animation( t_spell_effect_ptr window )
{
	m_spell_animation = window;
	change_active_spell_effect();
}

inline void t_combat_creature::set_waiting( bool arg )
{
	m_waiting = arg;
}




#endif // !defined( COMBAT_ACTOR_H_INCLUDED )